package sengine;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;

/**
 *
 * @author twoodf5611
 */
public class Texture {

    private int height, width;
    private ByteBuffer contents;
    private int texID = -1;
    
    private static final HashMap<String, Texture> cache = new HashMap<>();

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    public void loadTexture() {
        texID = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, getWidth(), getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, contents);
    }

    public int getID() {
        if (texID == -1) {
            loadTexture();
        }
        return texID;
    }

    public void activate() {
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, getID());
    }

    public static Texture loadTexture(BufferedImage src) {
        int[] pixels = new int[src.getWidth() * src.getHeight()];
        src.getRGB(0, 0, src.getWidth(), src.getHeight(), pixels, 0, src.getWidth());

        // Create a ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocateDirect(src.getWidth() * src.getHeight() * 4);

        // Iterate through all the pixels and add them to the ByteBuffer
        for (int y = 0; y < src.getHeight(); y++) {
            for (int x = 0; x < src.getWidth(); x++) {
                // Select the pixel
                int pixel = pixels[y * src.getWidth() + x];
                // Add the RED component
                buffer.put((byte) ((pixel >> 16) & 0xFF));
                // Add the GREEN component
                buffer.put((byte) ((pixel >> 8) & 0xFF));
                // Add the BLUE component
                buffer.put((byte) (pixel & 0xFF));
                // Add the ALPHA component
                buffer.put((byte) ((pixel >> 24) & 0xFF));
            }
        }

        buffer.flip();

        Texture ret = new Texture();
        ret.contents = buffer;
        ret.height = src.getHeight();
        ret.width = src.getWidth();
        return ret;
    }
    
    public static Texture loadTexture(String src) {
        Texture ret;
        if((ret=cache.get(src))==null) {
            try {
                ret = loadTexture(ImageIO.read(new File(src)));
                cache.put(src, ret);
            } catch(IOException ioe) {
                System.err.println("Couldn't load texture "+src);
                ioe.printStackTrace();
            }
        }
        return ret;
    }
}
